package com.seka.control.service;

import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.springframework.scheduling.config.TaskManagementConfigUtils;
import org.springframework.stereotype.Component;

import com.seka.control.common.annotation.SekaDiscoveryTask;
import com.seka.control.utils.BeanCacheUtil;
import com.seka.control.utils.SekaSpringContextHolder;

/**
 * 调度管理
 * @author mw
 *
 */
@Component
public class ScheduledManager {

	/**
	 * 日志
	 */
	private static final Logger LOG = LoggerFactory.getLogger(ScheduledManager.class);
	

	
	/**
	 * 开启定时
	 */
	public boolean open() {
		ConfigurableApplicationContext  context = (ConfigurableApplicationContext) SekaSpringContextHolder.getApplicationContext();
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
		
		BeanDefinitionBuilder genericBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
		beanFactory.registerBeanDefinition(TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME, genericBeanDefinition.getRawBeanDefinition());
		
		ScheduledAnnotationBeanPostProcessor sc = SekaSpringContextHolder.getBean(ScheduledAnnotationBeanPostProcessor.class);

		
		Map<String, Object> beanMap = BeanCacheUtil.getAll();
		if(beanMap ==null || beanMap.isEmpty()) {
			return false;
		}
		for (Entry<String, Object> entry : beanMap.entrySet()) {
			Object bean = getBean(entry.getKey());
			sc.postProcessAfterInitialization(bean, entry.getKey());
		}
		sc.setApplicationContext(null);
		sc.afterSingletonsInstantiated();
		return true;
	}
	
	
	/**
	 * 获取beanName
	 * @param className
	 * @return
	 */
	private Object getBean(String className) {
		Class<?> clazz =null;
		Object bean =null;
		try {
			clazz = Class.forName(className);
			if(clazz !=null) {
				SekaDiscoveryTask anno = clazz.getAnnotation(SekaDiscoveryTask.class);
				String beanName = anno.value();
				if(beanName !=null && !"".equals(beanName)) {
					bean = SekaSpringContextHolder.getBean(beanName);
				}else {
					bean = SekaSpringContextHolder.getBean(clazz);
				}
			}
			if(bean ==null) {
				String lassName = className.substring(className.lastIndexOf(".")+1, className.length());
				String firstChar = lassName.substring(0,1);
				lassName = lassName.replaceFirst(firstChar, firstChar.toLowerCase());
				bean = SekaSpringContextHolder.getBean(lassName);
			}
		} catch (ClassNotFoundException e) {
			LOG.error("获取bean 对象失败："+ className,e);
		}
		return bean;
		
	}
}
